package com.lan.model.symbol;


import com.lan.model.Symbol;

import java.util.LinkedList;
import java.util.List;

public abstract class Scope extends Symbol {

    // 该Scope中的成员，包括变量、方法、json等。
    protected List<Symbol> symbols = new LinkedList<>();

    /**
     * 向scope中添加符号，同时设置好该符号的scope
     *
     * @param symbol
     */
    public void add(Symbol symbol) {
        symbols.add(symbol);
        symbol.setScope(this);
    }


    /**
     * 是否包含某个Symbol
     *
     * @param symbol
     * @return
     */
    public boolean contains(Symbol symbol) {
        return symbols.contains(symbol);
    }


    /**
     * 是否包含某个Variable
     *
     * @param name
     * @return
     */
    public Variable getVariable(String name) {
        return getVariable(this, name);
    }

    public static Variable getVariable(Scope scope, String name) {
        for (Symbol s : scope.symbols) {
            if (s instanceof Variable && name.equalsIgnoreCase(s.getName())) {
                return (Variable) s;
            }
        }
        return null;
    }


    public Json getJson(String name) {
        return getJson(this, name);
    }

    public static Json getJson(Scope scope, String name) {
        for (Symbol s : scope.symbols) {
            if (s instanceof Json && name.equalsIgnoreCase(s.getName())) {
                return (Json) s;
            }
        }
        return null;
    }


    public Jarray getJarray(String name) {
        return getJarray(this, name);
    }


    public static Jarray getJarray(Scope scope, String name) {
        for (Symbol s : scope.symbols) {
            if (s instanceof Jarray && name.equalsIgnoreCase(s.getName())) {
                return (Jarray) s;
            }
        }
        return null;
    }


    /**
     * 是否包含某个Function
     *
     * @param name
     * @return
     */
    public Function getFunction(String name) {
        return getFunction(this, name);
    }

    /**
     * 是否包含某个Function。这是个静态方法，可以做为工具方法重用。避免类里要超找父类的情况。
     *
     * @param scope
     * @param name
     * @return
     */
    public static Function getFunction(Scope scope, String name) {
        Function rtn = null;
        for (Symbol s : scope.symbols) {
            if (s instanceof Function && name.equalsIgnoreCase(s.getName())) {
                rtn = (Function) s;
            }
        }
        return rtn;
    }


    public List<Symbol> getSymbols() {
        return symbols;
    }


    @Override
    public String toString() {
        return id + "_" + name;
    }

}